package typefilter;

import com.itheima.annotations.District;
import org.springframework.core.io.support.PropertiesLoaderUtils;
import org.springframework.core.type.filter.AbstractTypeHierarchyTraversingFilter;
import org.springframework.util.AntPathMatcher;
import org.springframework.util.ClassUtils;
import org.springframework.util.PathMatcher;

import java.io.IOException;
import java.util.Properties;

/***
 * spring的自定义扫描规则
 * @author 黑马程序员
 * @Company http://www.itheima.com
 */

public class DistrictTypeFilter extends AbstractTypeHierarchyTraversingFilter {

    //定义路径校验类对象
    private PathMatcher pathMatcher;

    // 注意:使用@Value注解的方式是获取不到配置值的。
    // 因为Spring的声明周期里，负责填充属性值的InstantiationAwareBeanPostProcessor 与 TypeFilter的实例化过程压根搭不上边。
    // @Value("${common.district.name}")
    private String districtName;

    /*** 默认构造函数 */
    public DistrictTypeFilter() {

        //1.第一个参数：不考虑基类。2.第二个参数：不考虑接口上的信息
        super(false, false);

        //借助Spring默认的Resource通配符路径方式
         pathMatcher = new AntPathMatcher();
        // 硬编码读取配置信息
        try {
            Properties loadAllProperties = PropertiesLoaderUtils.loadAllProperties("district.properties");
            districtName = loadAllProperties.getProperty("common.district.name");
        } catch (IOException e) {
            // TODO Auto-generated catch block e.printStackTrace(); } }//注意本类将注册为Exclude, 返回true代表拒绝 @Override
        }
    }

    //注意本类将注册为Exclude, 返回true代表拒绝
    @Override
    protected boolean matchClassName(String className) {
        try {
            if (!isPotentialPackageClass(className)) {
                return false;
            }
            // 判断当前区域是否和所配置的区域一致, 不一致则阻止载入Spring容器
            Class<?> clazz = ClassUtils.forName(className, DistrictTypeFilter.class.getClassLoader());
            District districtAnnotation = clazz.getAnnotation(District.class);
            if (null == districtAnnotation) {
                return false;
            }
            final String districtValue = districtAnnotation.value();
            return (!districtName.equalsIgnoreCase(districtValue));
        } catch (Exception e) {
            throw new RuntimeException(e);
        }
    }

    // 潜在的满足条件的类的类名, 指定package下
    private static final String PATTERN_STANDARD = ClassUtils.convertClassNameToResourcePath("com.itheima.service.*.*");

    // 本类逻辑中可以处理的类 -- 指定package下的才会进行逻辑判断,
    private boolean isPotentialPackageClass(String className) {
        // 将类名转换为资源路径, 以进行匹配测试
        final String path = ClassUtils.convertClassNameToResourcePath(className);
        return pathMatcher.match(PATTERN_STANDARD, path);
    }
}